package com.suiwei.base;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * @author suiwei
 * @date 2023-01-10 17:01
 */
@Slf4j
public class StringDemo {
  /** 字符串常用操作 */
  @Test
  void Base() {
    // 比较
    String s1 = "abc";
    String s2 = "abc";
    String s3 = new String("abc");
    System.out.println(s1 == s2); // true
    System.out.println(s1 == s3); // false
    System.out.println(s1.equals(s3)); // true
    log.info(String.valueOf("ABC".equals("abc"))); // false
    log.info(String.valueOf("ABC".equalsIgnoreCase("abc"))); // false
    // 其他
    log.info(String.valueOf("abc".length())); // 字符数，3
    log.info(String.valueOf(" a b c ".trim())); // 只去除两端的空格
    log.info(String.format("%06d", 5)); // 结果为000005。%是格式化输入接受参数的标记，0格式化命令：结果将用零来填充，6：填充位数，d：代表十进制数据
    log.info(String.valueOf("00".compareTo("01"))); // 比较两个字符串在ASCLL表中的先后顺序
    System.out.println(s1.charAt(1)); // b；根据索引找字符
    // 替换
    // 相同点：replace与replaceAll都是全部替换。不同点：replaceAll支持正则表达式，因此会对参数进行解析（两个参数均是），
    // 如replaceAll("\\d", "*")，把一个字符串所有的数字字符都换成星号；
    // 而replace则不会，replace("\\d","*")就是替换"\d"的字符串，而不会解析为正则
    log.info("abc".replace("b", "*")); // a*c
    log.info("ab\\c".replace("\\", "*")); // ab*c
    //  '\'在java中是一个转义字符，所以需要用两个代表一个。
    // 例如System.out.println( "\\" ) ;只打印出一个"\"。但是'\'也是正则表达式中的转义字符
    // 也需要用两个代表一个,所以是4个
    log.info("ab\\c".replaceAll("\\\\", "*")); // ab*c
    // 截取
    System.out.println("07:55:00".substring(0, 2)); // 07（包左不包右）
    System.out.println("07:55:00".substring(2)); // :55:00；从索引2开始（包括）-末位
    // 切割
    String[] arr = "a,bc,d".split(","); //
  }

  /** 其他类型与字符串的转换 */
  @Test
  void convert() {
    // 字符串 --> 数组
    String[] arr = "a,bc,d".split(","); // 字符串转字符串数组
    String[] arr2 = "a,bc@d".split("|,|@"); // 如果一个字符串中有多个分隔符，可以用"|"作为连字符。
    char[] charArr = "a,bc,d".toCharArray(); // 字符串转字符数组
    for (int i = 0; i < charArr.length; i++) { // 字符串遍历；先把字符串转成字符数组，再循环
      System.out.println(charArr[i]);
    }

    // 字符串 --> 基本类型(parseXXX(String)：返回基本类型)
    double num = Double.parseDouble("3.14");
    // 字符串 --> 返回的是包装类，点进方法内部还是parseDouble。实际用哪个都可以，就是多了个自动装箱拆箱的过程
    Double num1 = Double.valueOf("3.14");

    // 基本类型 --> 字符串
    String other = String.valueOf(true);
    String other2 = true + "";
    // 对象 --> 字符串
    String double1 = new Object().toString();
    // 其他转换
    String lover = "ABC".toLowerCase(); // 字符串转成小写
  }
  /**
   * StringUtils方法的操作对象是java.lang.String类型的对象，是JDK提供的String类型操作方法的补充。 StringUtils是null安全的，即如果输入参数
   * String 为null则不会抛出 NullPointerException ，而是做了相应处理。例如，如果输入为null则返回也是 null 等
   */
  @Test
  void StringUtils() {
    // 判断某字符串是否为空，为空的标准是 str==null 或 str.length()==0
    log.info(String.valueOf(StringUtils.isEmpty(null))); // true
    log.info(String.valueOf(StringUtils.isEmpty(""))); // true
    log.info(String.valueOf(StringUtils.isEmpty(" "))); // false
    // 判断某字符串是否为空，为空的标准是 str==null 或 str.length()==0 或 由空白符(whitespace)构成
    log.info(String.valueOf(StringUtils.isBlank(null))); // true
    log.info(String.valueOf(StringUtils.isBlank(""))); // true
    log.info(String.valueOf(StringUtils.isBlank(" "))); // true
    // 只有有一个为空，就返回true
    log.info(String.valueOf(StringUtils.isAnyEmpty(" ", "abc"))); // false
    log.info(String.valueOf(StringUtils.isAnyBlank(" ", "abc"))); // true
  }

  @Test
  void StringBuilderDemo() {
    //两种构造方法
    StringBuilder sb = new StringBuilder();//创建一个空的字符串缓冲区
    StringBuilder sb2 = new StringBuilder("abc");//创建一个字符串缓冲区，并初始化指定的参数内容

    //与String的转换
    StringBuilder sb3 = new StringBuilder("abc");//String --> StringBuilder
    String sb4 = sb3.toString();//StringBuilder --> String

    //append添加方法
    sb.append(1);
    sb.append(true);
    sb.append("abc").append("cde").append("fgh");//链式编程：调用的方法，返回的结果是对象，就可以继续向下调用方法
    System.out.println(sb);

    //其他方法
    System.out.println(sb.reverse());//将缓冲区的内容反转
    System.out.println(sb.length());//返回长度
    System.out.println(sb.toString().split("b")[0]);//调用的方法StringBuilder没有，String中有，就需要toSting方法转换后使用
  }
}
